function mxSwimlaneManager(graph, horizontal, siblings, bubbling)
{
	var self = this;

	this.addHandler = function(sender, evt)
	{
		if (self.isEnabled())
		{
			self.cellsAdded(evt.getArgAt(0));
		}
	};
	this.resizeHandler = function(sender, evt)
	{
		if (self.isEnabled())
		{
			self.cellsResized(evt.getArgAt(0));
		}
	};
	this.horizontal = (horizontal != null) ? horizontal : true;
	this.siblings = (siblings != null) ? siblings : true;
	this.bubbling = (bubbling != null) ? bubbling : true;
	this.setGraph(graph);
};
mxSwimlaneManager.prototype = new mxEventSource();
mxSwimlaneManager.prototype.constructor = mxSwimlaneManager;
mxSwimlaneManager.prototype.graph = null;
mxSwimlaneManager.prototype.enabled = true;
mxSwimlaneManager.prototype.horizontal = true;
mxSwimlaneManager.prototype.siblings = true;
mxSwimlaneManager.prototype.bubbling = true;
mxSwimlaneManager.prototype.addHandler = null;
mxSwimlaneManager.prototype.resizeHandler = null;
mxSwimlaneManager.prototype.isSwimlaneIgnored = function(swimlane)
{
	return !this.getGraph().isSwimlane(swimlane);
};
mxSwimlaneManager.prototype.isEnabled = function()
{
	return this.enabled;
};
mxSwimlaneManager.prototype.setEnabled = function(value)
{
	this.enabled = value;
};
mxSwimlaneManager.prototype.isHorizontal = function()
{
	return this.horizontal;
};
mxSwimlaneManager.prototype.setHorizontal = function(value)
{
	this.horizontal = value;
};
mxSwimlaneManager.prototype.isSiblings = function()
{
	return this.siblings;
};
mxSwimlaneManager.prototype.setSiblings = function(value)
{
	this.siblings = value;
};
mxSwimlaneManager.prototype.isBubbling = function()
{
	return this.bubbling;
};
mxSwimlaneManager.prototype.setBubbling = function(value)
{
	this.bubbling = value;
};
mxSwimlaneManager.prototype.getGraph = function()
{
	return this.graph;
};
mxSwimlaneManager.prototype.setGraph = function(graph)
{
	if (this.graph != null)
	{
		this.graph.removeListener(this.addHandler);
		this.graph.removeListener(this.resizeHandler);
	}
	this.graph = graph;

	if (this.graph != null)
	{
		this.graph.addListener(mxEvent.ADD_CELLS, this.addHandler);
		this.graph.addListener(mxEvent.CELLS_RESIZED, this.resizeHandler);
	}
};
mxSwimlaneManager.prototype.cellsAdded = function(cells)
{
	if (cells != null)
	{
		var model = this.getGraph().getModel();
		model.beginUpdate();

		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				if (!this.isSwimlaneIgnored(cells[i]))
				{
					this.swimlaneAdded(cells[i]);
				}
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};
mxSwimlaneManager.prototype.swimlaneAdded = function(swimlane)
{
	var model = this.getGraph().getModel();

	var geo = null;
	var parent = model.getParent(swimlane);
	var childCount = model.getChildCount(parent);

	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(parent, i);

		if (child != swimlane && !this.isSwimlaneIgnored(child))
		{
			geo = model.getGeometry(child);
			break;
		}
	}

	if (geo != null)
	{
		this.resizeSwimlane(swimlane, geo.width, geo.height);
	}
};
mxSwimlaneManager.prototype.cellsResized = function(cells)
{
	if (cells != null)
	{
		var model = this.getGraph().getModel();
		model.beginUpdate();

		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				if (!this.isSwimlaneIgnored(cells[i]))
				{
					this.swimlaneResized(cells[i]);
				}
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};
mxSwimlaneManager.prototype.swimlaneResized = function(swimlane)
{
	var model = this.getGraph().getModel();
	var geo = model.getGeometry(swimlane);

	if (geo != null)
	{
		var w = geo.width;
		var h = geo.height;
		model.beginUpdate();

		try
		{
			var parent = model.getParent(swimlane);

			if (this.isSiblings())
			{
				var childCount = model.getChildCount(parent);

				for (var i = 0; i < childCount; i++)
				{
					var child = model.getChildAt(parent, i);

					if (child != swimlane && !this.isSwimlaneIgnored(child))
					{
						this.resizeSwimlane(child, w, h);
					}
				}
			}

			if (this.isBubbling() && !this.isSwimlaneIgnored(parent))
			{
				this.resizeParent(parent, w, h);
				this.swimlaneResized(parent);
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};
mxSwimlaneManager.prototype.resizeSwimlane = function(swimlane, w, h)
{
	var model = this.getGraph().getModel();
	var geo = model.getGeometry(swimlane);

	if (geo != null)
	{
		geo = geo.clone();

		if (this.isHorizontal())
		{
			geo.width = w;
		}
		else
		{
			geo.height = h;
		}
		model.setGeometry(swimlane, geo);
	}
};
mxSwimlaneManager.prototype.resizeParent = function(parent, w, h)
{
	var graph = this.getGraph();
	var model = graph.getModel();
	var geo = model.getGeometry(parent);

	if (geo != null)
	{
		geo = geo.clone();
		var size = graph.getStartSize(parent)

		if (this.isHorizontal())
		{
			geo.width = w + size.width;
		}
		else
		{
			geo.height = h + size.height;
		}
		model.setGeometry(parent, geo);
	}
};
mxSwimlaneManager.prototype.destroy = function()
{
	this.setGraph(null);
};